package com.macro.mall.controller;

import cn.hutool.core.util.ObjectUtil;
import com.macro.mall.common.api.CommonPage;
import com.macro.mall.common.api.CommonResult;
import com.macro.mall.common.config.XhsApiConfig;
import com.macro.mall.common.exception.BaseException;
import com.macro.mall.common.exception.XhsApiException;
import com.macro.mall.dto.*;
import com.macro.mall.mapper.XhsStoreMapper;
import com.macro.mall.model.OmsOrder;
import com.macro.mall.model.XhsStore;
import com.macro.mall.model.XhsUser;
import com.macro.mall.model.request.*;
import com.macro.mall.model.request.order.CreateOrderRequest;
import com.macro.mall.model.request.order.SelOrderRequest;
import com.macro.mall.model.request.order.StoreDetailRequest;
import com.macro.mall.model.response.*;
import com.macro.mall.model.vo.order.OrderDetail;
import com.macro.mall.model.vo.order.OrderList;
import com.macro.mall.model.vo.store.StoreDetailVo;
import com.macro.mall.model.vo.user.SessionVo;
import com.macro.mall.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.Data;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.List;

/**
 * 订单管理Controller
 * Created by macro on 2018/10/11.
 */
@Controller
@Api(tags = "OmsOrderController")
@Tag(name = "OmsOrderController", description = "订单管理")
@RequestMapping("/order")
public class OmsOrderController {
    @Autowired
    private OmsOrderService orderService;

    @Resource
    private XhsApiConfig xhsApiConfig;

    @Resource
    private XhsStoreMapper xhsStoreMapper;

    @Resource
    private SessionService sessionService;

    @Resource
    private XhsPhoneService xhsPhoneService;

    @Resource
    private XhsUserService xhsUserService;

    @Resource
    private OkHttpClient okHttpClient;
    @Resource
    private XhsOrderService xhsOrderService;

    @Resource
    private XhsLoginService xhsLoginService;

    @ApiOperation("查询订单")
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult<CommonPage<OmsOrder>> list(OmsOrderQueryParam queryParam,
                                                   @RequestParam(value = "pageSize", defaultValue = "5") Integer pageSize,
                                                   @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum) {
        List<OmsOrder> orderList = orderService.list(queryParam, pageSize, pageNum);
        return CommonResult.success(CommonPage.restPage(orderList));
    }

    @ApiOperation("批量发货")
    @RequestMapping(value = "/update/delivery", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult delivery(@RequestBody List<OmsOrderDeliveryParam> deliveryParamList) {
        int count = orderService.delivery(deliveryParamList);
        if (count > 0) {
            return CommonResult.success(count);
        }
        return CommonResult.failed();
    }

    @ApiOperation("批量关闭订单")
    @RequestMapping(value = "/update/close", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult close(@RequestParam("ids") List<Long> ids, @RequestParam String note) {
        int count = orderService.close(ids, note);
        if (count > 0) {
            return CommonResult.success(count);
        }
        return CommonResult.failed();
    }

    @ApiOperation("批量删除订单")
    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult delete(@RequestParam("ids") List<Long> ids) {
        int count = orderService.delete(ids);
        if (count > 0) {
            return CommonResult.success(count);
        }
        return CommonResult.failed();
    }

    @ApiOperation("获取订单详情：订单信息、商品信息、操作记录")
    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult<OmsOrderDetail> detail(@PathVariable Long id) {
        OmsOrderDetail orderDetailResult = orderService.detail(id);
        return CommonResult.success(orderDetailResult);
    }

    @ApiOperation("修改收货人信息")
    @RequestMapping(value = "/update/receiverInfo", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult updateReceiverInfo(@RequestBody OmsReceiverInfoParam receiverInfoParam) {
        int count = orderService.updateReceiverInfo(receiverInfoParam);
        if (count > 0) {
            return CommonResult.success(count);
        }
        return CommonResult.failed();
    }

    @ApiOperation("修改订单费用信息")
    @RequestMapping(value = "/update/moneyInfo", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult updateReceiverInfo(@RequestBody OmsMoneyInfoParam moneyInfoParam) {
        int count = orderService.updateMoneyInfo(moneyInfoParam);
        if (count > 0) {
            return CommonResult.success(count);
        }
        return CommonResult.failed();
    }

    @ApiOperation("备注订单")
    @RequestMapping(value = "/update/note", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult updateNote(@RequestParam("id") Long id,
                                   @RequestParam("note") String note,
                                   @RequestParam("status") Integer status) {
        int count = orderService.updateNote(id, note, status);
        if (count > 0) {
            return CommonResult.success(count);
        }
        return CommonResult.failed();
    }











    /**
     * 获取预授权码
     * @return 预授权码响应
     */
    @ApiOperation("获取预授权码")
    @RequestMapping(value = "/preAuthCode", method = RequestMethod.GET)
    @ResponseBody
    public XhsPreAuthCodeResponse getPreAuthCode() {
        System.out.println("开始获取小红书预授权码");
        XhsPreAuthCodeResponse response = xhsOrderService.getPreAuthCode();
        System.out.println(response);
        return response;
    }








    @ApiOperation("创建小红书订单")
    @RequestMapping(value = "/create", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult createOrder(@RequestBody CreateOrderRequest request) {
        OrderUpsertResponse order = xhsOrderService.createOrder(request);
        return CommonResult.success(order.getData());
    }




    @ApiOperation("查询小红书订单列表")
    @RequestMapping(value = "/selXhsOrder", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult selXhsOrder(@RequestBody SelOrderRequest request) {
        List<OrderList> orderLists = xhsOrderService.selXhsOrder(request);
        return CommonResult.success(orderLists);
    }



    @ApiOperation("查询店铺详情")
    @RequestMapping(value = "/getStoreDetail", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult getStoreDetail(@RequestBody StoreDetailRequest storeDetailRequest) {
        StoreDetailVo storeDetailVo =  xhsOrderService.getStoreDetail(storeDetailRequest);

        return CommonResult.success(storeDetailVo);
    }






    @ApiOperation("核销订单")
    @RequestMapping(value = "/verify", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult verify(@RequestBody VoucherVerifyRequest request)
            throws Exception {


        String outOrderByVoucherCode = xhsOrderService.getOutOrderByVoucherCode(request.getVoucherInfos().get(0).getVoucherCode());
        request.setOutOrderId(outOrderByVoucherCode);
        xhsOrderService.verifyVoucher(request);
         // 修改订单状态，同步订单核销门店
        xhsOrderService.updateOrder(request);

        return CommonResult.success(true);
    }








    /**
     * 根据券码列表查询核销信息
     * @return 包含核销信息的响应DTO
     *
     * @apiNote 该接口支持最多100个券码的批量查询
     * @example POST /api/coupon/verify/byCouponCodes
     *          Headers: app_id=your_app_id, access_token=your_access_token
     *          Body: ["CODE123","CODE456"]
     */
    @ApiOperation("根据券码列表查询核销信息")
    @RequestMapping(value = "/byCouponCodes", method = RequestMethod.POST)
    @ResponseBody
    public CouponVerifyResponseDTO getByCouponCodes(@RequestBody CouponCodeRequest request) {

        return xhsOrderService.getByCouponCodes(request.getCoupon_code_list());
    }

    /**
     * 根据订单ID列表查询核销信
     * @return 包含核销信息的响应DTO
     *
     * @apiNote 该接口支持最多50个订单ID的批量查询
     * @example POST /api/coupon/verify/byOrderIds
     *          Headers: app_id=your_app_id, access_token=your_access_token
     *          Body: ["ORDER123","ORDER456"]
     */
    @ApiOperation("根据订单ID列表查询核销信")
    @RequestMapping(value = "/byOrderIds", method = RequestMethod.POST)
    @ResponseBody
    public CouponVerifyResponseDTO getByOrderIds(@RequestBody CouponCodeRequest request) {

        return xhsOrderService.getByOrderIds(request.getOrder_id_list());
    }

    /**
     * 综合查询核销信息（可同时使用券码和订单ID查询）
     * @param request 包含券码列表和订单ID列表的请求DTO
     * @return 包含核销信息的响应DTO
     *
     * @apiNote 该接口支持组合查询，券码最多100个，订单ID最多50个
     * @example POST /api/coupon/verify/detail
     *          Headers: app_id=your_app_id, access_token=your_access_token
     *          Body: {"couponCodeList":["CODE123"],"orderIdList":["ORDER456"]}
     */
    @ApiOperation("综合查询核销信息（可同时使用券码和订单ID查询）")
    @RequestMapping(value = "/detail", method = RequestMethod.POST)
    @ResponseBody
    public CouponVerifyResponseDTO getVerifyDetail(
            @RequestBody CouponVerifyRequestDTO request) {

        return xhsOrderService.getVerifyDetail(
                request.getCoupon_code_list(),
                request.getOrder_id_list()
        );
    }


    /**
     * 查询担保订单信息
     * @param request
     * @return
     */
    @ApiOperation("查询订单详情")
    @RequestMapping(value = "/xhsOrderDetail", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult getOrderInfo(@RequestBody XhsGpayOrderQueryRequest request) {
//        XhsGpayOrderQueryResponse response = null;
//        try {
//            response = xhsOrderService.queryGpayOrder(request);
//        } catch (Exception e) {
//            throw new RuntimeException(e);
//        }
//        return CommonResult.success(response);

        OrderDetail orderDetail =   xhsOrderService.getOrderInfo(request);
     return    CommonResult.success(orderDetail);
    }






    @ApiOperation("解密手机号数据")
    @RequestMapping(value = "/decrypt", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult<XhsPhoneDecryptResponse> decryptPhoneNumber(
            @Validated @RequestBody XhsPhoneDecryptRequest request,
            @RequestHeader("X-Session-Key") String sessionKey) {
        try {
            XhsPhoneDecryptResponse response = xhsPhoneService.decryptPhoneNumber(request, sessionKey);
            return CommonResult.success(response);
        } catch (Exception e) {
            return CommonResult.failed(e.getMessage());
        }
    }

    @ApiOperation("简化版解密手机号数据")
    @PostMapping("/decrypt/simple")
    public CommonResult<XhsPhoneDecryptResponse> decryptPhoneNumberSimple(
            @RequestParam String encryptedData,
            @RequestParam String iv,
            @RequestHeader("X-Session-Key") String sessionKey) {
        try {
            XhsPhoneDecryptResponse response = xhsPhoneService.decryptPhoneNumberSimple(
                    encryptedData, iv, sessionKey);
            return CommonResult.success(response);
        } catch (Exception e) {
            return CommonResult.failed(e.getMessage());
        }
    }






    @ApiOperation("获取openId")
    @RequestMapping(value = "/code2Session", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult code2Session(@RequestParam String code) {
        Code2SessionRequest request = new Code2SessionRequest();
        request.setCode(code);
        Code2SessionResponse code2SessionResponse = xhsOrderService.code2Session(request);
        SessionVo sessionVo = new SessionVo();
        sessionVo.setOpenid(code2SessionResponse.getData().getOpenid());
        sessionVo.setSession_key(code2SessionResponse.getData().getSession_key());

        XhsUser byOpenId = xhsUserService.getByOpenId(sessionVo.getOpenid());
        if (ObjectUtil.isNotEmpty(byOpenId)){
            sessionVo.setPhone(byOpenId.getPhoneNumber());
        }
        if ( ObjectUtil.isNotEmpty(byOpenId) &&   ObjectUtil.isNotEmpty(byOpenId.getPhoneNumber())){
            XhsStore xhsStore = xhsStoreMapper.selectByPhone(byOpenId.getPhoneNumber());
            if (ObjectUtil.isNotEmpty(xhsStore)){
                sessionVo.setStore(true);
                sessionVo.setStoreId(xhsStore.getPoiId());
            }
        }
        return CommonResult.success(sessionVo);
    }




    @ApiOperation("获取登录信息")
    @RequestMapping(value = "/auth/code2Session", method = RequestMethod.GET)
    @ResponseBody
    public Code2SessionResponse code2Session2(@RequestParam String code) {
        Code2SessionRequest request = new Code2SessionRequest();
        request.setCode(code);
        return sessionService.code2Session(request);
    }





    @ApiOperation("查询token")
    @RequestMapping(value = "/xhs", method = RequestMethod.GET)
    @ResponseBody
    public XhsLoginController.XhsResponse login(@RequestParam String code) {

        // 2. 获取有效access_token
        String accessToken = null;
        try {
            accessToken = xhsLoginService.getValidToken();
        } catch (XhsApiException e) {
            throw new RuntimeException(e);
        }
        if (!StringUtils.hasText(accessToken)) {
            throw new BaseException("获取access_token失败");
        }
        // 构建请求URL
        HttpUrl url = HttpUrl.parse(xhsApiConfig.getBaseUrl() + "/api/rmp/session").newBuilder()

                .addQueryParameter("app_id", xhsApiConfig.getAppId())
                .addQueryParameter("access_token", accessToken)
                .addQueryParameter("code", code)
                .build();

        // 创建请求
        Request request = new Request.Builder()
                .url(url)
                .get()
                .build();

        try (Response response = okHttpClient.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                return handleErrorResponse(response);
            }

            // 解析响应
            okhttp3.ResponseBody body = response.body();
            if (body != null) {
                // 实际实现需要完整的JSON解析
                // 这里使用简化示例，建议使用Jackson完整解析
                String responseBody = body.string();
                return parseResponse(responseBody);
            }
            return new XhsLoginController.XhsResponse(false, "Empty response", -1, null);
        } catch (IOException e) {
            return new XhsLoginController.XhsResponse(false, "API request failed: " + e.getMessage(), -500, null);
        }
    }




    // 解析响应（需要根据实际响应结构调整）
    private XhsLoginController.XhsResponse parseResponse(String responseBody) {
        // 实际实现应使用JSON解析库（如Jackson）
        // 这里演示基本结构，建议创建完整的DTO类
        if (responseBody.contains("\"code\":0")) {
            return new XhsLoginController.XhsResponse(true, "success", 0, new XhsLoginController.XhsData("openid_demo", "session_key_demo"));
        }
        return new XhsLoginController.XhsResponse(false, "Unknown error", -1, null);
    }

    private XhsLoginController.XhsResponse handleErrorResponse(Response response) {
        return new XhsLoginController.XhsResponse(false,
                "API Error: " + response.message(),
                response.code(),
                null);
    }

    // 响应DTO
    @Data
    static class XhsResponse {
        private Boolean success;
        private String msg;
        private Integer code;
        private XhsLoginController.XhsData data;

        public XhsResponse(boolean success, String msg, Integer code, XhsLoginController.XhsData data) {
            this.success = success;
            this.msg = msg;
            this.code = code;
            this.data = data;
        }
    }

    @Data
    static class XhsData {
        private String openid;
        private String session_key;

        public XhsData(String openid, String session_key) {
            this.openid = openid;
            this.session_key = session_key;
        }
    }


}
